/**
 *  链表（双向）
 *  @param Array arr 用于初始化的数组
 *  @property 内置属性
 *      head 链表头结点
 *      tail 链表尾结点
 *      size 链表当前节点数
 *  @metods 内置方法
 *      init(Array)： 传入单词数组，重新初始化链表
 *      shift()： 将头部第一个节点删除，成功则返回删除的节点值
 *      pop()： 将尾部第一个节点删除，成功则返回删除的节点值
 *      unshift(val)： 在头部插入一个节点，成功则返回当前链表的长度
 *      append(val)： 在尾部插入一个节点，成功则返回当前链表的长度
 *      delete(node)： 删除指定节点，成功则返回当前链表的长度
 *      getValList()： 将链表节点值按顺序存放数组返回
 *      getNode(index)： 传入一个整数，返回第 index 个节点
 *  @returns {TrieTree}
 *  */ 
const linkLineNode = function (key = "", val = "") {
    this.val = val;
    this.key = key;
    this.pre = null;
    this.next = null;
};
class LinkLine{
    constructor(arr = []){
        this.init(arr);
    }
    init(arr = []){
        const head = new linkLineNode("head", "head");
        const tail = new linkLineNode("tail", "tail");
        head.next = tail;
        tail.pre = head;
        this.head = head;
        this.tail = tail;
        this.size = 0;
        for(const str of arr){
            this.append(str);
        }
    }
    isEmpty(){
        return this.head.next == this.tail;
    }
    shift(){
        if(this.isEmpty()) return false;
        const node = this.head.next;
        this.head.next = this.head.next.next;
        this.head.next.pre = this.head;
        this.size--;
        return node.val;
    }
    pop(){
        if(this.isEmpty()) return false;
        const node = this.tail.pre;
        this.tail.pre = this.tail.pre.pre;
        this.tail.pre.next = this.tail;
        this.size--;
        return node.val;
    }
    unshift(val){
        if(!val) return -1;
        const node = new linkLineNode('node',val);
        node.next = this.head.next;
        node.pre = this.head;
        this.head.next.pre = node;
        this.head.next = node;
        this.size++;
        return this.size;
    }
    append(val){
        if(!val) return -1;
        const node = new linkLineNode('node',val);
        node.next = this.tail;
        node.pre = this.tail.pre;
        this.tail.pre.next = node;
        this.tail.pre = node;
        this.size++;
        return this.size;
    }
    delete(node){
        try{
            node.pre.next = node.next;
            node.next.pre = node.pre;
            this.size--;
        }catch(err){
            return -1;
        }
        return this.size;
    }
    getValList(){
        const arr = [];
        let headNode = this.head;
        while(headNode.next != this.tail){
            headNode = headNode.next;
            arr.push(headNode.val);
        }
        return arr;
    }
    getNode(index){
        let node = this.head;
        while(index--){
            node = node.next;
            if(!node) return null;
        }
        return node;
    }
}
exports.LinkLine = LinkLine;